home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / lisp / gcl-1.000 / gcl-1 / gcl-1.0 / c / big.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-07  |  7.9 KB  |  466 lines

  1.   /* Copyright William F. Schelter 1991
  2.    Bignum routines.
  3.  
  4.  
  5.    
  6. num_arith.c: add_int_big
  7. num_arith.c: big_minus
  8. num_arith.c: big_plus
  9. num_arith.c: big_quotient_remainder
  10. num_arith.c: big_sign
  11. num_arith.c: big_times
  12. num_arith.c: complement_big
  13. num_arith.c: copy_big
  14. num_arith.c: div_int_big
  15. num_arith.c: mul_int_big
  16. num_arith.c: normalize_big
  17. num_arith.c: normalize_big_to_object
  18. num_arith.c: stretch_big
  19. num_arith.c: sub_int_big
  20. num_comp.c: big_compare
  21. num_comp.c: big_sign
  22. num_log.c: big_sign
  23. num_log.c: copy_to_big
  24. num_log.c: normalize_big
  25. num_log.c: normalize_big_to_object
  26. num_log.c: stretch_big
  27. num_pred.c: big_sign
  28. number.c: big_to_double
  29. predicate.c: big_compare
  30. typespec.c: big_sign
  31. print.d: big_minus
  32. print.d: big_sign
  33. print.d: big_zerop
  34. print.d: copy_big
  35. print.d: div_int_big
  36. read.d: add_int_big
  37. read.d: big_to_double
  38. read.d: complement_big
  39. read.d: mul_int_big
  40. read.d: normalize_big
  41. read.d: normalize_big_to_object
  42.  
  43.  */
  44.  
  45.  
  46.  
  47. #define remainder gclremainder
  48. #include "include.h"
  49. #include "mp.h"
  50.  
  51.  
  52.  
  53.  
  54. #define BCOPY_BODY(x,y) \
  55. do { int *ucop = (int *)(x); \
  56.     int *vcop = (int *) (y); \
  57.   {int j = lgef(ucop); \
  58.     while(--j >= 0) \
  59.       { *vcop++ = *ucop++;}}}while (0)
  60.  
  61. bcopy_body(x,y)
  62.     GEN x,y;
  63. {BCOPY_BODY(x,y);}
  64.  
  65.  
  66.  
  67.  
  68. /* coerce a pari GEN to a bignum or fixnum */
  69.  
  70. object
  71. make_integer(u)
  72. GEN u;
  73. { int l = lgef(u);
  74.   if (l > (MP_CODE_WORDS+1) ||
  75.       ( l == (MP_CODE_WORDS+1)  &&
  76.        (MP_ONLY_WORD(u) & (1<<31)) != 0
  77.        && (MP_ONLY_WORD(u) == ( 1<<31) ? signe(u) > 0 : 1)))
  78.     { object ans ;
  79.       GEN w;
  80.       big_register_1->big.big_length = lg(u);
  81.       big_register_1->big.big_self = u;
  82.       ans = alloc_object(t_bignum);
  83.       ans->big.big_self = 0;
  84.       w = (GEN)alloc_relblock(l*sizeof(int));
  85.       /* may have been relocated */
  86.       u =   big_register_1->big.big_self ;
  87.       ans->big.big_self = w;
  88.       ans->big.big_length = l;
  89.       BCOPY_BODY(u , w);
  90.       setlg(w,l);
  91.       return ans;
  92.     }
  93.   else
  94.     if (signe(u) > 0) return make_fixnum(MP_ONLY_WORD(u));
  95.   else
  96.     if (signe(u) < 0) return make_fixnum(-MP_ONLY_WORD(u));
  97.   else
  98.     return(small_fixnum(0));
  99.  }
  100.  
  101.  
  102. object
  103. make_bignum(u)
  104. GEN u;
  105.     { object ans = alloc_object(t_bignum);
  106.       GEN w;
  107.       ans->big.big_length = lg(u);
  108.       /* save u */
  109.       ans->big.big_self = u;
  110.       w = (GEN)alloc_relblock(lg(u)*sizeof(int));
  111.       /* restore  u */
  112.       u = ans->big.big_self ;
  113.       ans->big.big_self = w;
  114.       BCOPY_BODY(u ,  ans->big.big_self);
  115.       return ans;
  116.      }
  117.  
  118. big_zerop(x)
  119.  object x;
  120. { return (signe(MP(x))== 0);}
  121.  
  122. big_compare(x, y)
  123.      object x,y;
  124. {return cmpii(MP(x),MP(y));}
  125.  
  126. object
  127. big_minus(x)
  128.      object x;
  129. { object y; 
  130.   setsigne(MP(x),-(signe(MP(x))));
  131.   y = make_integer(MP(x));
  132.   setsigne(MP(x),-(signe(MP(x))));
  133.   return  y;
  134. }
  135.  
  136. gcopy_to_big(res,x)
  137.      GEN res;
  138.      object x;
  139. {int l = (x)->big.big_length;
  140.  int lgres = lg(res);
  141.  if (l< lgres)
  142.     { 
  143.       big_register_1->big.big_length = lgres;
  144.       big_register_1->big.big_self = res;
  145.       (x)->big.big_self = (GEN) alloc_relblock(lgres*sizeof(int));
  146.       (x)->big.big_length = lgres; 
  147.       res =    big_register_1->big.big_self ;
  148.      }
  149.  BCOPY_BODY(res,(x)->big.big_self);
  150.   if (l>lgres)
  151.     { setlg((x)->big.big_self, l);}
  152.         
  153.  
  154. add_int_big(i, x)
  155. int i;
  156. object x;
  157. {
  158.        MPOP_DEST(x,addsi,i,MP(x));
  159. }
  160.  
  161.  
  162. sub_int_big(i, x)
  163. int i;
  164. object x;
  165. { MPOP_DEST(x,subsi,i,MP(x));
  166. }
  167.  
  168. mul_int_big(i, x)
  169. int i;
  170. object x;
  171. { MPOP_DEST(x,mulsi,i,MP(x));
  172. }    
  173.  
  174. /*
  175.     Div_int_big(i, x) destructively divides non-negative bignum x
  176.     by positive int i.
  177.     X will hold the quotient from  the division.
  178.     Div_int_big(i, x) returns the remainder of the division.
  179.     I should be positive.
  180.     X should be non-negative.
  181. */
  182.  
  183. div_int_big(i, x)
  184. int i;
  185. object x;
  186. { save_avma;
  187.   GEN res = divis(MP(x),i);
  188.   gcopy_to_big(res,x);
  189.   restore_avma;
  190.   return hiremainder;
  191. }
  192.  
  193.  
  194. object
  195. big_plus(x, y)
  196. object x,y;
  197. { MPOP(return,addii,MP(x),MP(y));
  198. }
  199.  
  200. object
  201. big_times(x, y)
  202. object x,y;
  203. { MPOP(return,mulii,MP(x),MP(y));
  204. }
  205.  
  206.  
  207.  
  208. big_quotient_remainder(x0, y0, qp, rp)
  209.      object x0,y0,*qp,*rp;
  210. {
  211.   GEN res,quot;
  212.   save_avma;
  213.   res = dvmdii(MP(x0),MP(y0),");
  214.   *qp = make_integer(res);
  215.   *rp = make_integer(quot);
  216.   restore_avma;
  217.   return;
  218.  
  219. }
  220.  
  221.     
  222. double
  223. big_to_double(x)
  224.      object x;
  225. {
  226.     double d, e;
  227.     GEN u = MP(x);
  228.     unsigned int *w;
  229.     int l;
  230.     e =  4.294967296e9;
  231.  
  232.     l = lgef(u);
  233.     MP_START_HIGH(w,(unsigned int *) u,l);
  234.     l = l - MP_CODE_WORDS;
  235.  
  236.     if (l == 0) return 0.0;
  237.  
  238.     d = (double) MP_NEXT_DOWN(w);
  239.     while (--l > 0)
  240.       {d = e*d + (double)(MP_NEXT_DOWN(w));}
  241.     if (signe(u)>0) return d;
  242.       else return -d;
  243.       }
  244.     
  245.  
  246. object
  247. normalize_big_to_object(x)
  248.  object x;
  249. { return make_integer(MP(x));}
  250.   
  251.  
  252. object copy_big(x)
  253.      object x;
  254. {
  255.   if (type_of(x)==t_bignum)
  256.     return make_bignum(MP(x));
  257.   else FEerror("bignum expected",0);
  258.  
  259. }
  260.  
  261.  
  262. object
  263. copy_to_big(x)
  264.      object x;
  265. {object y;
  266.  
  267.     if (type_of(x) == t_fixnum) {
  268.       save_avma;
  269.       y = make_bignum(stoi(fix(x)));
  270.       restore_avma;
  271.     } else if (type_of(x) == t_bignum)
  272.         y = copy_big(x);
  273.     else
  274.         FEerror("integer expected",0);
  275.     return(y);
  276.       }
  277.   
  278.  
  279. /* return the power of x */
  280. GEN
  281. powerii(x,y)
  282.      GEN x, y;
  283. {  GEN ans = gun;
  284.    if (signe(y) < 0) FEerror("bad");
  285.    while (lgef(y) > 2){
  286.      if (MP_LOW(y,lgef(y)) & 1)
  287.        { ans = mulii(ans,x);}
  288.      x = mulii(x,x);
  289.      y = shifti(y,-1);}
  290.    return ans;
  291.  }
  292.  
  293. object integ_temp;
  294.  
  295.  
  296. replace_copy1(x,y)
  297.      GEN y,x;
  298. { int j = lgef(x);
  299.  if (y && j <= lg(y))
  300.     { x++; y++;
  301.       while (--j >0)
  302.       {*y++ = *x++;}
  303.      return 0;}
  304.  END:
  305.  return j*2*sizeof(GEN);
  306. }
  307.  
  308. /* doubles the length ! */
  309. GEN
  310. replace_copy2(x,y)
  311.      GEN y,x;
  312. {GEN yp = y;  
  313.  int k,j = lgef(x);
  314.  k = j;
  315.  while (--j >=0)
  316.    {*yp++ = *x++;}
  317.  y[0] = INT_FLAG + k*2;
  318.  return y;}
  319.  
  320. #define STOI(x,y) do{ \
  321.   if (x ==0) { y[1]=2;} \
  322.   else if((x)>0) {y[1]=0x1000003;y[2]=x;} \
  323.                   else{y[1]=0xff000003;y[2]= -x;}}while (0)
  324.  
  325. /* actually y == 0 is not supposed to happen !*/
  326.             
  327. obj_replace_copy1(x,y)
  328.      object x;
  329.      GEN y;
  330. { int j ;
  331.   GEN xp;
  332.   { if (type_of(x) == t_bignum)
  333.       {   j = lgef(MP(x));
  334.       if (y && j <= lg(y))
  335.         { xp=MP(x);
  336.           xp++; y++;
  337.           while (--j >0)
  338.         {*y++ = *xp++;}
  339.           return 0;}}
  340.   else
  341.     { if (y==0) return 3*2*sizeof(GEN) ;
  342.       STOI(fix(x),y); return 0;}}
  343.  END:
  344.  return j*2*sizeof(GEN);
  345. }
  346.  
  347. /* doubles the length ! */
  348. GEN
  349. obj_replace_copy2(x,y)
  350.      object x;
  351.      GEN y;
  352. {GEN yp = y;
  353.  GEN xp;
  354.  int k,j;
  355.  if (type_of(x) == t_bignum)
  356.    { j = lgef(MP(x));
  357.      k = j;
  358.      xp = MP(x);
  359.      while (--j >=0)
  360.        {*yp++ = *xp++;}
  361.      y[0] = INT_FLAG + k*2;}
  362.  else  {STOI(fix(x),yp); y[0] = INT_FLAG+3*2;}
  363.  return y;}
  364.  
  365.  
  366. GEN
  367. otoi(x)
  368.      object x;
  369. {if (type_of(x)==t_fixnum) return stoi(fix(x));
  370.  if (type_of(x)==t_bignum)
  371.    return (MP(x));
  372.  FEwrong_type_argument(Sinteger,x);
  373.  return 0;
  374. }
  375.  
  376. object
  377. alloc_bignum_static(len)
  378. int len;
  379.     { object ans = alloc_object(t_bignum);
  380.       GEN w;
  381.       ans->big.big_length = len;
  382.       ans->big.big_self = 0;
  383.       w = (GEN)AR_ALLOC(alloc_contblock,len,unsigned long);
  384.       ans->big.big_self = w;
  385.       w[0] = INT_FLAG + len;
  386.       return ans;
  387.      }
  388.  
  389.  
  390. GEN
  391. setq_io(x,all,val)
  392.      GEN x;
  393.      object val;
  394.      object *all;
  395. {int n= obj_replace_copy1(val,x);
  396.  if (n)
  397.    { *all = alloc_bignum_static(n/sizeof(int));
  398.      return obj_replace_copy2(val,MP(*all));
  399.    }
  400.  else return x;}
  401.  
  402.  
  403. GEN
  404. setq_ii(x,all,val)
  405.      GEN x;
  406.      GEN val;
  407.      object *all;
  408. {int n= replace_copy1(val,x);
  409.  if (n)
  410.    { *all = alloc_bignum_static(n/sizeof(int));
  411.      return replace_copy2(val,MP(*all));
  412.    }
  413.  else return x;}
  414.  
  415.  
  416.  
  417.  
  418. void
  419. isetq_fix(var,s)
  420.      GEN var;
  421.      int s;
  422. {/* if (var==0) FEerror("unitialized integer var"); */
  423.  STOI(s,var);
  424. }
  425.  
  426. GEN
  427. icopy_bignum(a,y)
  428.      object a;
  429.      GEN y;
  430. { int *ucop = (int *)MP(a); 
  431.   int *vcop = (int *) (y);
  432.   int j = lgef(ucop);
  433.   {while(--j >= 0) 
  434.      { *vcop++ = *ucop++;}
  435.    setlg(y,a->big.big_length);
  436.    return y;}}
  437.      
  438.  
  439. GEN
  440. icopy_fixnum(a,y)
  441.      object a;
  442.      GEN y;
  443.        
  444. { int x= fix(a);
  445.   if(!x) return gzero;
  446.   y[0]=INT_FLAG+3;
  447.   if(x>0) {y[1]=0x1000003;y[2]=x;}
  448.   else{y[1]=0xff000003;y[2]= -x;}
  449.   return y;
  450. }
  451.      
  452.  
  453.  
  454.      
  455.  
  456.  
  457.   
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.